home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / ustring.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  31.2 KB  |  998 lines

  1. // -*- c++ -*-
  2. #ifndef _GLIBMM_USTRING_H
  3. #define _GLIBMM_USTRING_H
  4.  
  5. /* $Id: ustring.h,v 1.12 2005/01/21 19:26:04 murrayc Exp $ */
  6.  
  7. /* Copyright (C) 2002 The gtkmm Development Team
  8.  *
  9.  * This library is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Library General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2 of the License, or (at your option) any later version.
  13.  *
  14.  * This library is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Library General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Library General Public
  20.  * License along with this library; if not, write to the Free
  21.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include <glib/gmacros.h>
  25. #include <glib/gunicode.h>
  26. #include <glibmm/unicode.h>
  27.  
  28. #include <iosfwd>
  29. #include <iterator>
  30. #include <string>
  31.  
  32. #include <glibmmconfig.h>
  33. GLIBMM_USING_STD(bidirectional_iterator_tag)
  34. GLIBMM_USING_STD(reverse_iterator)
  35. GLIBMM_USING_STD(string)
  36. GLIBMM_USING_STD(istream)
  37. GLIBMM_USING_STD(ostream)
  38.  
  39. #ifdef GLIBMM_HAVE_STD_ITERATOR_TRAITS
  40. GLIBMM_USING_STD(iterator_traits)
  41. #else
  42. #include <cstddef> /* for ptrdiff_t */
  43. GLIBMM_USING_STD(random_access_iterator_tag)
  44. #endif
  45.  
  46.  
  47. namespace Glib
  48. {
  49.  
  50. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  51. #ifndef GLIBMM_HAVE_STD_ITERATOR_TRAITS
  52.  
  53. template <class T>
  54. struct IteratorTraits
  55. {
  56.   typedef typename T::iterator_category iterator_category;
  57.   typedef typename T::value_type        value_type;
  58.   typedef typename T::difference_type   difference_type;
  59.   typedef typename T::pointer           pointer;
  60.   typedef typename T::reference         reference;
  61. };
  62.  
  63. template <class T>
  64. struct IteratorTraits<T*>
  65. {
  66.   typedef std::random_access_iterator_tag iterator_category;
  67.   typedef T                               value_type;
  68.   typedef ptrdiff_t                       difference_type;
  69.   typedef T*                              pointer;
  70.   typedef T&                              reference;
  71. };
  72.  
  73. template <class T>
  74. struct IteratorTraits<const T*>
  75. {
  76.   typedef std::random_access_iterator_tag iterator_category;
  77.   typedef T                               value_type;
  78.   typedef ptrdiff_t                       difference_type;
  79.   typedef const T*                        pointer;
  80.   typedef const T&                        reference;
  81. };
  82.  
  83. #endif /* GLIBMM_HAVE_STD_ITERATOR_TRAITS */
  84. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  85.  
  86.  
  87. /** The iterator type of Glib::ustring.
  88.  * Note this is not a random access iterator but a bidirectional one,
  89.  * since all index operations need to iterate over the UTF-8 data.  Use
  90.  * std::advance() to move to a certain position.  However, all of the
  91.  * relational operators are available:
  92.  * <tt>== != < > <= >=</tt>
  93.  *
  94.  * A writeable iterator isn't provided because:  The number of bytes of
  95.  * the old UTF-8 character and the new one to write could be different.
  96.  * Therefore, any write operation would invalidate all other iterators
  97.  * pointing into the same string.
  98.  */
  99. template <class T>
  100. class ustring_Iterator
  101. {
  102. public:
  103.   typedef std::bidirectional_iterator_tag   iterator_category;
  104.   typedef gunichar                          value_type;
  105.   typedef std::string::difference_type      difference_type;
  106.   typedef value_type                        reference;
  107.   typedef void                              pointer;
  108.  
  109.   inline ustring_Iterator();
  110.   inline ustring_Iterator(const ustring_Iterator<std::string::iterator>& other);
  111.  
  112.   inline value_type operator*() const;
  113.  
  114.   inline ustring_Iterator<T> &     operator++();
  115.   inline const ustring_Iterator<T> operator++(int);
  116.   inline ustring_Iterator<T> &     operator--();
  117.   inline const ustring_Iterator<T> operator--(int);
  118.  
  119.   explicit inline ustring_Iterator(T pos);
  120.   inline T base() const;
  121.  
  122. private:
  123.   T pos_;
  124. };
  125.  
  126.  
  127. /** Extract a UCS-4 character from UTF-8 data.
  128.  * Convert a single UTF-8 (multibyte) character starting at @p pos to
  129.  * a UCS-4 wide character.  This may read up to 6 bytes after the start
  130.  * position, depending on the UTF-8 character width.  You have to make
  131.  * sure the source contains at least one valid UTF-8 character.
  132.  *
  133.  * This is mainly used by the implementation of Glib::ustring::iterator,
  134.  * but it might be useful as utility function if you prefer using
  135.  * std::string even for UTF-8 encoding.
  136.  */
  137. gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_PURE;
  138.  
  139.  
  140. /** Glib::ustring has much the same interface as std::string, but contains
  141.  * %Unicode characters encoded as UTF-8.
  142.  *
  143.  * @par About UTF-8 and ASCII
  144.  * @par
  145.  * The standard character set ANSI_X3.4-1968 -- more commonly known as
  146.  * ASCII -- is a subset of UTF-8.  So, if you want to, you can use
  147.  * Glib::ustring without even thinking about UTF-8.
  148.  * @par
  149.  * Whenever ASCII is mentioned in this manual, we mean the @em real ASCII
  150.  * (i.e. as defined in ANSI_X3.4-1968), which contains only 7-bit characters.
  151.  * Glib::ustring can @em not be used with ASCII-compatible extended 8-bit
  152.  * charsets like ISO-8859-1.  It's a good idea to avoid string literals
  153.  * containing non-ASCII characters (e.g. German umlauts) in source code,
  154.  * or at least you should use UTF-8 literals.
  155.  * @par
  156.  * You can find a detailed UTF-8 and %Unicode FAQ here:
  157.  * http://www.cl.cam.ac.uk/~mgk25/unicode.html
  158.  *
  159.  * @par Glib::ustring vs. std::string
  160.  * @par
  161.  * Glib::ustring has implicit type conversions to and from std::string.
  162.  * These conversions do @em not convert to/from the current locale (see
  163.  * Glib::locale_from_utf8() and Glib::locale_to_utf8() if you need that).  You
  164.  * can always use std::string instead of Glib::ustring -- however, using
  165.  * std::string with multi-byte characters is quite hard.  For instance,
  166.  * <tt>std::string::operator[]</tt> might return a byte in the middle of a
  167.  * character, and <tt>std::string::length()</tt> returns the number of bytes
  168.  * rather than characters.  So don't do that without a good reason.
  169.  * @par
  170.  * In a perfect world the C++ Standard Library would contain a UTF-8 string
  171.  * class.  Unfortunately, the C++ standard doesn't mention UTF-8 at all.  Note
  172.  * that std::wstring is not a UTF-8 string class because it contains only
  173.  * fixed-width characters (where width could be 32, 16, or even 8 bits).
  174.  *
  175.  * @par Glib::ustring and stream input/output
  176.  * @par
  177.  * The stream I/O operators, that is operator<<() and operator>>(), perform
  178.  * implicit charset conversion to/from the current locale.  If that's not
  179.  * what you intented (e.g. when writing to a configuration file that should
  180.  * always be UTF-8 encoded) use ustring::raw() to override this behaviour.
  181.  * @par
  182.  * If you're using std::ostringstream to build strings for display in the
  183.  * user interface, you must convert the result back to UTF-8 as shown below:
  184.  * @code
  185.  * std::ostringstream output;
  186.  * output.imbue(std::locale("")); // use the user's locale for this stream
  187.  * output << percentage << " % done";
  188.  * label->set_text(Glib::locale_to_utf8(output.str()));
  189.  * @endcode
  190.  *
  191.  * @par Implementation notes
  192.  * @par
  193.  * Glib::ustring does not inherit from std::string, because std::string was
  194.  * intended to be a final class.  For instance, it does not have a virtual
  195.  * destructor.  Also, a HAS-A relationship is more appropriate because
  196.  * ustring can't just enhance the std::string interface.  Rather, it has to
  197.  * reimplement the interface so that all operations are based on characters
  198.  * instead of bytes.
  199.  */
  200. class ustring
  201. {
  202. public:
  203.   typedef std::string::size_type                        size_type;
  204.   typedef std::string::difference_type                  difference_type;
  205.  
  206.   typedef gunichar                                      value_type;
  207.   typedef gunichar &                                    reference;
  208.   typedef const gunichar &                              const_reference;
  209.  
  210.   typedef ustring_Iterator<std::string::iterator>       iterator;
  211.   typedef ustring_Iterator<std::string::const_iterator> const_iterator;
  212.  
  213. #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
  214.  
  215.   typedef std::reverse_iterator<iterator>               reverse_iterator;
  216.   typedef std::reverse_iterator<const_iterator>         const_reverse_iterator;
  217.  
  218. #else
  219.  
  220.   typedef std::reverse_iterator<iterator,
  221.                                 iterator::iterator_category,
  222.                                 iterator::value_type,
  223.                                 iterator::reference,
  224.                                 iterator::pointer,
  225.                                 iterator::difference_type> reverse_iterator;
  226.   typedef std::reverse_iterator<const_iterator,
  227.                                 const_iterator::iterator_category,
  228.                                 const_iterator::value_type,
  229.                                 const_iterator::reference,
  230.                                 const_iterator::pointer,
  231.                                 const_iterator::difference_type> const_reverse_iterator;
  232.  
  233. #endif /* GLIBMM_HAVE_SUN_REVERSE_ITERATOR */
  234.  
  235. #ifdef GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS
  236.   static const size_type npos = std::string::npos;
  237. #else
  238.   //The IRIX MipsPro compiler says "The indicated constant value is not known",
  239.   //so we need to initalize the static member data elsewhere.
  240.   static const size_type npos;
  241. #endif
  242.  
  243.   /*! Default constructor, which creates an empty string.
  244.    */
  245.   ustring();
  246.   
  247.   ~ustring();
  248.  
  249.   /*! Construct a ustring as a copy of another ustring.
  250.    * @param other A source string.
  251.    */
  252.   ustring(const ustring& other);
  253.  
  254.   /*! Assign the value of another string to this string.
  255.    * @param other A source string.
  256.    */ 
  257.   ustring& operator=(const ustring& other);
  258.  
  259.   /*! Swap contents with another string.
  260.    * @param other String to swap with.
  261.    */
  262.   void swap(ustring& other);
  263.  
  264.   /*! Construct a ustring as a copy of another std::string.
  265.    * @param src A source <tt>std::string</tt> containing text encoded as UTF-8.
  266.    */
  267.   ustring(const std::string& src);
  268.  
  269.   /*! Construct a ustring as a copy of a substring.
  270.    * @param src %Source ustring.
  271.    * @param i Index of first character to copy from.
  272.    * @param n Number of characters to copy (defaults to copying the remainder).
  273.    */
  274.   ustring(const ustring& src, size_type i, size_type n=npos);
  275.  
  276.   /*! Construct a ustring as a partial copy of a C string.
  277.    * @param src %Source C string encoded as UTF-8.
  278.    * @param n Number of characters to copy.
  279.    */
  280.   ustring(const char* src, size_type n);
  281.  
  282.   /*! Construct a ustring as a copy of a C string.
  283.    * @param src %Source C string encoded as UTF-8.
  284.    */
  285.   ustring(const char* src);
  286.  
  287.   /*! Construct a ustring as multiple characters.
  288.    * @param n Number of characters.
  289.    * @param uc UCS-4 code point to use.
  290.    */  
  291.   ustring(size_type n, gunichar uc);
  292.  
  293.   /*! Construct a ustring as multiple characters.
  294.    * @param n Number of characters.
  295.    * @param c ASCII character to use.
  296.    */  
  297.   ustring(size_type n, char c);
  298.  
  299.   /*! Construct a ustring as a copy of a range.
  300.    * @param pbegin Start of range.
  301.    * @param pend End of range.
  302.    */  
  303.   template <class In> ustring(In pbegin, In pend);
  304.  
  305.  
  306. //! @name Assign new contents.
  307. //! @{
  308.  
  309.   ustring& operator=(const std::string& src);
  310.   ustring& operator=(const char* src);
  311.   ustring& operator=(gunichar uc);
  312.   ustring& operator=(char c);
  313.  
  314.   ustring& assign(const ustring& src);
  315.   ustring& assign(const ustring& src, size_type i, size_type n);
  316.   ustring& assign(const char* src, size_type n);
  317.   ustring& assign(const char* src);
  318.   ustring& assign(size_type n, gunichar uc);
  319.   ustring& assign(size_type n, char c);
  320.   template <class In> ustring& assign(In pbegin, In pend);
  321.  
  322. //! @}
  323. //! @name Append to the string.
  324. //! @{
  325.  
  326.   ustring& operator+=(const ustring& src);
  327.   ustring& operator+=(const char* src);
  328.   ustring& operator+=(gunichar uc);
  329.   ustring& operator+=(char c);
  330.   void push_back(gunichar uc);
  331.   void push_back(char c);
  332.  
  333.   ustring& append(const ustring& src);
  334.   ustring& append(const ustring& src, size_type i, size_type n);
  335.   ustring& append(const char* src, size_type n);
  336.   ustring& append(const char* src);
  337.   ustring& append(size_type n, gunichar uc);
  338.   ustring& append(size_type n, char c);
  339.   template <class In> ustring& append(In pbegin, In pend);
  340.  
  341. //! @}
  342. //! @name Insert into the string.
  343. //! @{
  344.  
  345.   ustring& insert(size_type i, const ustring& src);
  346.   ustring& insert(size_type i, const ustring& src, size_type i2, size_type n);
  347.   ustring& insert(size_type i, const char* src, size_type n);
  348.   ustring& insert(size_type i, const char* src);
  349.   ustring& insert(size_type i, size_type n, gunichar uc);
  350.   ustring& insert(size_type i, size_type n, char c);
  351.  
  352.   iterator insert(iterator p, gunichar uc);
  353.   iterator insert(iterator p, char c);
  354.   void     insert(iterator p, size_type n, gunichar uc);
  355.   void     insert(iterator p, size_type n, char c);
  356.   template <class In> void insert(iterator p, In pbegin, In pend);
  357.  
  358. //! @}
  359. //! @name Replace sub-strings.
  360. //! @{
  361.  
  362.   ustring& replace(size_type i, size_type n, const ustring& src);
  363.   ustring& replace(size_type i, size_type n, const ustring& src, size_type i2, size_type n2);
  364.   ustring& replace(size_type i, size_type n, const char* src, size_type n2);
  365.   ustring& replace(size_type i, size_type n, const char* src);
  366.   ustring& replace(size_type i, size_type n, size_type n2, gunichar uc);
  367.   ustring& replace(size_type i, size_type n, size_type n2, char c);
  368.  
  369.   ustring& replace(iterator pbegin, iterator pend, const ustring& src);
  370.   ustring& replace(iterator pbegin, iterator pend, const char* src, size_type n);
  371.   ustring& replace(iterator pbegin, iterator pend, const char* src);
  372.   ustring& replace(iterator pbegin, iterator pend, size_type n, gunichar uc);
  373.   ustring& replace(iterator pbegin, iterator pend, size_type n, char c);
  374.   template <class In> ustring& replace(iterator pbegin, iterator pend, In pbegin2, In pend2);
  375.  
  376. //! @}
  377. //! @name Erase sub-strings.
  378. //! @{
  379.  
  380.   void clear();
  381.   ustring& erase(size_type i, size_type n=npos);
  382.   ustring& erase();
  383.   iterator erase(iterator p);
  384.   iterator erase(iterator pbegin, iterator pend);
  385.  
  386. //! @}
  387. //! @name Compare and collate.
  388. //! @{
  389.  
  390.   int compare(const ustring& rhs) const;
  391.   int compare(const char* rhs)    const;
  392.   int compare(size_type i, size_type n, const ustring& rhs) const;
  393.   int compare(size_type i, size_type n, const ustring& rhs, size_type i2, size_type n2) const;
  394.   int compare(size_type i, size_type n, const char* rhs, size_type n2) const;
  395.   int compare(size_type i, size_type n, const char* rhs) const;
  396.  
  397.   /*! Create a unique sorting key for the UTF-8 string.  If you need to
  398.    * compare UTF-8 strings regularly, e.g. for sorted containers such as
  399.    * <tt>std::set<></tt>, you should consider creating a collate key first
  400.    * and compare this key instead of the actual string.
  401.    *
  402.    * The ustring::compare() methods as well as the relational operators
  403.    * <tt>== != < > <= >=</tt> are quite costly
  404.    * because they have to deal with %Unicode and the collation rules defined by
  405.    * the current locale.  Converting both operands to UCS-4 is just the first
  406.    * of several costly steps involved when comparing ustrings.  So be careful.
  407.    */
  408.   std::string collate_key() const;
  409.  
  410.   /*! Create a unique key for the UTF-8 string that can be used for caseless
  411.    * sorting.  <tt>ustr.casefold_collate_key()</tt> results in the same string
  412.    * as <tt>ustr.casefold().collate_key()</tt>, but the former is likely more
  413.    * efficient.
  414.    */
  415.   std::string casefold_collate_key() const;
  416.  
  417. //! @}
  418. //! @name Extract characters and sub-strings.
  419. //! @{
  420.  
  421.   /*! No reference return; use replace() to write characters. */
  422.   value_type operator[](size_type i) const;
  423.  
  424.   /*! No reference return; use replace() to write characters. @throw std::out_of_range */
  425.   value_type at(size_type i) const;
  426.  
  427.   inline ustring substr(size_type i=0, size_type n=npos) const;
  428.  
  429. //! @}
  430. //! @name Access a sequence of characters.
  431. //! @{
  432.  
  433.   iterator begin();
  434.   iterator end();
  435.   const_iterator begin() const;
  436.   const_iterator end()   const;
  437.   reverse_iterator rbegin();
  438.   reverse_iterator rend();
  439.   const_reverse_iterator rbegin() const;
  440.   const_reverse_iterator rend()   const;
  441.  
  442. //! @}
  443. //! @name Find sub-strings.
  444. //! @{
  445.  
  446.   size_type find(const ustring& str, size_type i=0) const;
  447.   size_type find(const char* str, size_type i, size_type n) const;
  448.   size_type find(const char* str, size_type i=0) const;
  449.   size_type find(gunichar uc, size_type i=0) const;
  450.   size_type find(char c, size_type i=0) const;
  451.  
  452.   size_type rfind(const ustring& str, size_type i=npos) const;
  453.   size_type rfind(const char* str, size_type i, size_type n) const;
  454.   size_type rfind(const char* str, size_type i=npos) const;
  455.   size_type rfind(gunichar uc, size_type i=npos) const;
  456.   size_type rfind(char c, size_type i=npos) const;
  457.  
  458. //! @}
  459. //! @name Match against a set of characters.
  460. //! @{
  461.  
  462.   size_type find_first_of(const ustring& match, size_type i=0) const;
  463.   size_type find_first_of(const char* match, size_type i, size_type n) const;
  464.   size_type find_first_of(const char* match, size_type i=0) const;
  465.   size_type find_first_of(gunichar uc, size_type i=0) const;
  466.   size_type find_first_of(char c, size_type i=0) const;
  467.  
  468.   size_type find_last_of(const ustring& match, size_type i=npos) const;
  469.   size_type find_last_of(const char* match, size_type i, size_type n) const;
  470.   size_type find_last_of(const char* match, size_type i=npos) const;
  471.   size_type find_last_of(gunichar uc, size_type i=npos) const;
  472.   size_type find_last_of(char c, size_type i=npos) const;
  473.  
  474.   size_type find_first_not_of(const ustring& match, size_type i=0) const;
  475.   size_type find_first_not_of(const char* match, size_type i, size_type n) const;
  476.   size_type find_first_not_of(const char* match, size_type i=0) const;
  477.   size_type find_first_not_of(gunichar uc, size_type i=0) const;
  478.   size_type find_first_not_of(char c, size_type i=0) const;
  479.  
  480.   size_type find_last_not_of(const ustring& match, size_type i=npos) const;
  481.   size_type find_last_not_of(const char* match, size_type i, size_type n) const;
  482.   size_type find_last_not_of(const char* match, size_type i=npos) const;
  483.   size_type find_last_not_of(gunichar uc, size_type i=npos) const;
  484.   size_type find_last_not_of(char c, size_type i=npos) const;
  485.  
  486. //! @}
  487. //! @name Retrieve the string's size.
  488. //! @{
  489.  
  490.   /** Returns true if the string is empty. Equivalent to *this == "".
  491.    * @result Whether the string is empty.
  492.    */
  493.   bool empty()  const;
  494.  
  495.   /** Returns the number of characters in the string, not including any null-termination.
  496.    * @result The number of UTF-8 characters.
  497.    *
  498.    * @see bytes(), empty() 
  499.    */
  500.   size_type size()   const;
  501.  
  502.   //We have length() as well as size(), because std::string has both.
  503.  
  504.   /** This is the same as size().
  505.    */
  506.   size_type length() const;
  507.   
  508.   /** Returns the number of bytes in the string, not including any null-termination.
  509.    * @result The number of bytes.
  510.    *
  511.    * @see size(), empty()
  512.    */
  513.   size_type bytes()  const;
  514.  
  515. //! @}
  516. //! @name Change the string's size.
  517. //! @{
  518.  
  519.   void resize(size_type n, gunichar uc);
  520.   void resize(size_type n, char c='\0');
  521.  
  522. //! @}
  523. //! @name Control the allocated memory.
  524. //! @{
  525.  
  526.   size_type capacity() const;
  527.   size_type max_size() const;
  528.   void reserve(size_type n=0);
  529.  
  530. //! @}
  531. //! @name Get a per-byte representation of the string.
  532. //! @{
  533.  
  534.   inline operator std::string() const; // e.g. std::string str = ustring();
  535.   inline const std::string& raw() const;
  536.  
  537.   // Not necessarily an ASCII char*. Use g_utf8_*() where necessary.
  538.   const char* data()  const;
  539.   const char* c_str() const;
  540.  
  541.   /*! @return Number of copied @em bytes, not characters. */
  542.   size_type copy(char* dest, size_type n, size_type i=0) const;
  543.  
  544. //! @}
  545. //! @name UTF-8 utilities.
  546. //! @{
  547.  
  548.   /*! Check whether the string is valid UTF-8. */
  549.   bool validate() const;
  550.  
  551.   /*! Check whether the string is valid UTF-8. */
  552.   bool validate(iterator& first_invalid);
  553.  
  554.   /*! Check whether the string is valid UTF-8. */
  555.   bool validate(const_iterator& first_invalid) const;
  556.  
  557.   /*! Check whether the string is plain 7-bit ASCII. @par
  558.    * Unlike any other ustring method, is_ascii() is safe to use on invalid
  559.    * UTF-8 strings.  If the string isn't valid UTF-8, it cannot be valid
  560.    * ASCII either, therefore is_ascii() will just return @c false then.
  561.    * @return Whether the string contains only ASCII characters.
  562.    */
  563.   bool is_ascii() const;
  564.  
  565.   /*! "Normalize" the %Unicode character representation of the string. */
  566.   ustring normalize(NormalizeMode mode = NORMALIZE_DEFAULT_COMPOSE) const;
  567.  
  568. //! @}
  569. //! @name Character case conversion.
  570. //! @{
  571.  
  572.   /*! Returns a new UTF-8 string with all characters characters converted to
  573.    * their lowercase equivalent, while honoring the current locale.  The
  574.    * resulting string may change in the number of bytes as well as in the
  575.    * number of characters.  For instance, the German sharp s
  576.    * <tt>"ß"</tt> will be replaced by two characters
  577.    * <tt>"SS"</tt> because there is no capital <tt>"ß"</tt>.
  578.    */
  579.   ustring uppercase() const;
  580.  
  581.   /*! Returns a new UTF-8 string with all characters characters converted to
  582.    * their lowercase equivalent, while honoring the current locale.  The
  583.    * resulting string may change in the number of bytes as well as in the
  584.    * number of characters.
  585.    */
  586.   ustring lowercase() const;
  587.  
  588.   /*! Returns a caseless representation of the UTF-8 string.  The resulting
  589.    * string doesn't correspond to any particular case, therefore the result
  590.    * is only useful to compare strings and should never be displayed to the
  591.    * user.
  592.    */
  593.   ustring casefold() const;
  594.  
  595. //! @}
  596.  
  597. private:
  598.  
  599. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  600.  
  601. #ifdef GLIBMM_HAVE_STD_ITERATOR_TRAITS
  602.   template <class In, class ValueType = typename std::iterator_traits<In>::value_type>
  603. #else
  604.   template <class In, class ValueType = typename Glib::IteratorTraits<In>::value_type>
  605. #endif
  606.   struct SequenceToString;
  607.   
  608.   //The Tru64 compiler needs these partial specializations to be declared here,
  609.   //as well as defined later. That's probably correct. murrayc.
  610.   template <class In>
  611.   struct SequenceToString<In, char>;
  612.  
  613.   template <class In>
  614.   struct SequenceToString<In, gunichar>;
  615.   
  616.   /*
  617.   template <>
  618.   struct ustring::SequenceToString<Glib::ustring::iterator, gunichar>;
  619.  
  620.   template <>
  621.   struct ustring::SequenceToString<Glib::ustring::const_iterator, gunichar>;
  622.   */
  623.   
  624. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  625.  
  626.   std::string string_;
  627. };
  628.  
  629.  
  630. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  631.  
  632. template <class In, class ValueType>
  633. struct ustring::SequenceToString
  634. {};
  635.  
  636. template <class In>
  637. struct ustring::SequenceToString<In, char> : public std::string
  638. {
  639.   SequenceToString(In pbegin, In pend);
  640. };
  641.  
  642. template <class In>
  643. struct ustring::SequenceToString<In, gunichar> : public std::string
  644. {
  645.   SequenceToString(In pbegin, In pend);
  646. };
  647.  
  648. template <>
  649. struct ustring::SequenceToString<Glib::ustring::iterator, gunichar> : public std::string
  650. {
  651.   SequenceToString(Glib::ustring::iterator pbegin, Glib::ustring::iterator pend);
  652. };
  653.  
  654. template <>
  655. struct ustring::SequenceToString<Glib::ustring::const_iterator, gunichar> : public std::string
  656. {
  657.   SequenceToString(Glib::ustring::const_iterator pbegin, Glib::ustring::const_iterator pend);
  658. };
  659.  
  660. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  661.  
  662.  
  663. /** Stream input operator.
  664.  * @relates Glib::ustring
  665.  * @throw Glib::ConvertError
  666.  */
  667. std::istream& operator>>(std::istream& is, Glib::ustring& utf8_string);
  668.  
  669. /** Stream output operator.
  670.  * @relates Glib::ustring
  671.  * @throw Glib::ConvertError
  672.  */
  673. std::ostream& operator<<(std::ostream& os, const Glib::ustring& utf8_string);
  674.  
  675.  
  676. /***************************************************************************/
  677. /*  Inline implementation                                                  */
  678. /***************************************************************************/
  679.  
  680. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  681.  
  682. /**** Glib::ustring_Iterator<> *********************************************/
  683.  
  684. template <class T> inline
  685. ustring_Iterator<T>::ustring_Iterator(T pos)
  686. :
  687.   pos_ (pos)
  688. {}
  689.  
  690. template <class T> inline
  691. T ustring_Iterator<T>::base() const
  692. {
  693.   return pos_;
  694. }
  695.  
  696. template <class T> inline
  697. ustring_Iterator<T>::ustring_Iterator()
  698. :
  699.   pos_ ()
  700. {}
  701.  
  702. template <class T> inline
  703. ustring_Iterator<T>::ustring_Iterator(const ustring_Iterator<std::string::iterator>& other)
  704. :
  705.   pos_ (other.base())
  706. {}
  707.  
  708. template <class T> inline
  709. typename ustring_Iterator<T>::value_type ustring_Iterator<T>::operator*() const
  710. {
  711.   return Glib::get_unichar_from_std_iterator(pos_);
  712. }
  713.  
  714. template <class T> inline
  715. ustring_Iterator<T>& ustring_Iterator<T>::operator++()
  716. {
  717.   pos_ += g_utf8_skip[static_cast<unsigned char>(*pos_)];
  718.   return *this;
  719. }
  720.  
  721. template <class T> inline
  722. const ustring_Iterator<T> ustring_Iterator<T>::operator++(int)
  723. {
  724.   const ustring_Iterator<T> temp (*this);
  725.   this->operator++();
  726.   return temp;
  727. }
  728.  
  729. template <class T> inline
  730. ustring_Iterator<T>& ustring_Iterator<T>::operator--()
  731. {
  732.   do --pos_; while((*pos_ & '\xC0') == '\x80');
  733.   return *this;
  734. }
  735.  
  736. template <class T> inline
  737. const ustring_Iterator<T> ustring_Iterator<T>::operator--(int)
  738. {
  739.   const ustring_Iterator<T> temp (*this);
  740.   this->operator--();
  741.   return temp;
  742. }
  743.  
  744. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  745.  
  746.  
  747. /** @relates Glib::ustring_Iterator */
  748. template <class T> inline
  749. bool operator==(const ustring_Iterator<T>& lhs, const ustring_Iterator<T>& rhs)
  750. {
  751.   return (lhs.base() == rhs.base());
  752. }
  753.  
  754. /** @relates Glib::ustring_Iterator */
  755. template <class T> inline
  756. bool operator!=(const ustring_Iterator<T>& lhs, const ustring_Iterator<T>& rhs)
  757. {
  758.   return (lhs.base() != rhs.base());
  759. }
  760.  
  761. /** @relates Glib::ustring_Iterator */
  762. template <class T> inline
  763. bool operator<(const ustring_Iterator<T>& lhs, const ustring_Iterator<T>& rhs)
  764. {
  765.   return (lhs.base() < rhs.base());
  766. }
  767.  
  768. /** @relates Glib::ustring_Iterator */
  769. template <class T> inline
  770. bool operator>(const ustring_Iterator<T>& lhs, const ustring_Iterator<T>& rhs)
  771. {
  772.   return (lhs.base() > rhs.base());
  773. }
  774.  
  775. /** @relates Glib::ustring_Iterator */
  776. template <class T> inline
  777. bool operator<=(const ustring_Iterator<T>& lhs, const ustring_Iterator<T>& rhs)
  778. {
  779.   return (lhs.base() <= rhs.base());
  780. }
  781.  
  782. /** @relates Glib::ustring_Iterator */
  783. template <class T> inline
  784. bool operator>=(const ustring_Iterator<T>& lhs, const ustring_Iterator<T>& rhs)
  785. {
  786.   return (lhs.base() >= rhs.base());
  787. }
  788.  
  789.  
  790. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  791.  
  792. /**** Glib::ustring::SequenceToString **************************************/
  793.  
  794. template <class In>
  795. ustring::SequenceToString<In,char>::SequenceToString(In pbegin, In pend)
  796. :
  797.   std::string(pbegin, pend)
  798. {}
  799.  
  800. template <class In>
  801. ustring::SequenceToString<In,gunichar>::SequenceToString(In pbegin, In pend)
  802. {
  803.   char utf8_buf[6]; // stores a single UTF-8 character
  804.  
  805.   for(; pbegin != pend; ++pbegin)
  806.   {
  807.     const std::string::size_type utf8_len = g_unichar_to_utf8(*pbegin, utf8_buf);
  808.     this->append(utf8_buf, utf8_len);
  809.   }
  810. }
  811.  
  812.  
  813. /**** Glib::ustring ********************************************************/
  814.  
  815. template <class In>
  816. ustring::ustring(In pbegin, In pend)
  817. :
  818.   string_ (Glib::ustring::SequenceToString<In>(pbegin, pend))
  819. {}
  820.  
  821. template <class In>
  822. ustring& ustring::assign(In pbegin, In pend)
  823. {
  824.   Glib::ustring::SequenceToString<In> temp_string (pbegin, pend);
  825.   string_.swap(temp_string); // constant-time operation
  826.   return *this;
  827. }
  828.  
  829. template <class In>
  830. ustring& ustring::append(In pbegin, In pend)
  831. {
  832.   string_.append(Glib::ustring::SequenceToString<In>(pbegin, pend));
  833.   return *this;
  834. }
  835.  
  836. template <class In>
  837. void ustring::insert(ustring::iterator p, In pbegin, In pend)
  838. {
  839.   string_.insert(p.base(), Glib::ustring::SequenceToString<In>(pbegin, pend));
  840. }
  841.  
  842. template <class In>
  843. ustring& ustring::replace(ustring::iterator pbegin, ustring::iterator pend, In pbegin2, In pend2)
  844. {
  845.   string_.replace(
  846.       pbegin.base(), pend.base(),
  847.       Glib::ustring::SequenceToString<In>(pbegin2, pend2));
  848.   return *this;
  849. }
  850.  
  851. // The ustring methods substr() and operator std::string() are inline,
  852. // so that the compiler has a fair chance to optimize the copy ctor away.
  853.  
  854. inline
  855. ustring ustring::substr(ustring::size_type i, ustring::size_type n) const
  856. {
  857.   return ustring(*this, i, n);
  858. }
  859.  
  860. inline
  861. ustring::operator std::string() const
  862. {
  863.   return string_;
  864. }
  865.  
  866. inline
  867. const std::string& ustring::raw() const
  868. {
  869.   return string_;
  870. }
  871.  
  872. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  873.  
  874.  
  875. /** @relates Glib::ustring */
  876. inline
  877. void swap(ustring& lhs, ustring& rhs)
  878. {
  879.   lhs.swap(rhs);
  880. }
  881.  
  882.  
  883. /**** Glib::ustring -- comparison operators ********************************/
  884.  
  885. /** @relates Glib::ustring */
  886. inline bool operator==(const ustring& lhs, const ustring& rhs)
  887.   { return (lhs.compare(rhs) == 0); }
  888.  
  889. /** @relates Glib::ustring */
  890. inline bool operator==(const ustring& lhs, const char* rhs)
  891.   { return (lhs.compare(rhs) == 0); }
  892.  
  893. /** @relates Glib::ustring */
  894. inline bool operator==(const char* lhs, const ustring& rhs)
  895.   { return (rhs.compare(lhs) == 0); }
  896.  
  897.  
  898. /** @relates Glib::ustring */
  899. inline bool operator!=(const ustring& lhs, const ustring& rhs)
  900.   { return (lhs.compare(rhs) != 0); }
  901.  
  902. /** @relates Glib::ustring */
  903. inline bool operator!=(const ustring& lhs, const char* rhs)
  904.   { return (lhs.compare(rhs) != 0); }
  905.  
  906. /** @relates Glib::ustring */
  907. inline bool operator!=(const char* lhs, const ustring& rhs)
  908.   { return (rhs.compare(lhs) != 0); }
  909.  
  910.  
  911. /** @relates Glib::ustring */
  912. inline bool operator<(const ustring& lhs, const ustring& rhs)
  913.   { return (lhs.compare(rhs) < 0); }
  914.  
  915. /** @relates Glib::ustring */
  916. inline bool operator<(const ustring& lhs, const char* rhs)
  917.   { return (lhs.compare(rhs) < 0); }
  918.  
  919. /** @relates Glib::ustring */
  920. inline bool operator<(const char* lhs, const ustring& rhs)
  921.   { return (rhs.compare(lhs) > 0); }
  922.  
  923.  
  924. /** @relates Glib::ustring */
  925. inline bool operator>(const ustring& lhs, const ustring& rhs)
  926.   { return (lhs.compare(rhs) > 0); }
  927.  
  928. /** @relates Glib::ustring */
  929. inline bool operator>(const ustring& lhs, const char* rhs)
  930.   { return (lhs.compare(rhs) > 0); }
  931.  
  932. /** @relates Glib::ustring */
  933. inline bool operator>(const char* lhs, const ustring& rhs)
  934.   { return (rhs.compare(lhs) < 0); }
  935.  
  936.  
  937. /** @relates Glib::ustring */
  938. inline bool operator<=(const ustring& lhs, const ustring& rhs)
  939.   { return (lhs.compare(rhs) <= 0); }
  940.  
  941. /** @relates Glib::ustring */
  942. inline bool operator<=(const ustring& lhs, const char* rhs)
  943.   { return (lhs.compare(rhs) <= 0); }
  944.  
  945. /** @relates Glib::ustring */
  946. inline bool operator<=(const char* lhs, const ustring& rhs)
  947.   { return (rhs.compare(lhs) >= 0); }
  948.  
  949.  
  950. /** @relates Glib::ustring */
  951. inline bool operator>=(const ustring& lhs, const ustring& rhs)
  952.   { return (lhs.compare(rhs) >= 0); }
  953.  
  954. /** @relates Glib::ustring */
  955. inline bool operator>=(const ustring& lhs, const char* rhs)
  956.   { return (lhs.compare(rhs) >= 0); }
  957.  
  958. /** @relates Glib::ustring */
  959. inline bool operator>=(const char* lhs, const ustring& rhs)
  960.   { return (rhs.compare(lhs) <= 0); }
  961.  
  962.  
  963. /**** Glib::ustring -- concatenation operators *****************************/
  964.  
  965. /** @relates Glib::ustring */
  966. inline ustring operator+(const ustring& lhs, const ustring& rhs)
  967.   { ustring temp (lhs); temp += rhs; return temp; }
  968.  
  969. /** @relates Glib::ustring */
  970. inline ustring operator+(const ustring& lhs, const char* rhs)
  971.   { ustring temp (lhs); temp += rhs; return temp; }
  972.  
  973. /** @relates Glib::ustring */
  974. inline ustring operator+(const char* lhs, const ustring& rhs)
  975.   { ustring temp (lhs); temp += rhs; return temp; }
  976.  
  977. /** @relates Glib::ustring */
  978. inline ustring operator+(const ustring& lhs, gunichar rhs)
  979.   { ustring temp (lhs); temp += rhs; return temp; }
  980.  
  981. /** @relates Glib::ustring */
  982. inline ustring operator+(gunichar lhs, const ustring& rhs)
  983.   { ustring temp (1, lhs); temp += rhs; return temp; }
  984.  
  985. /** @relates Glib::ustring */
  986. inline ustring operator+(const ustring& lhs, char rhs)
  987.   { ustring temp (lhs); temp += rhs; return temp; }
  988.  
  989. /** @relates Glib::ustring */
  990. inline ustring operator+(char lhs, const ustring& rhs)
  991.   { ustring temp (1, lhs); temp += rhs; return temp; }
  992.  
  993. } // namespace Glib
  994.  
  995.  
  996. #endif /* _GLIBMM_USTRING_H */
  997.  
  998.